package com.sparrow.manage.monitor;

import com.sparrow.manage.access.AccessPVService;
import com.sparrow.manage.util.SpringBean;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * 访问监听器
 */
public class AccessMonitor {

    private static final Logger logger = LoggerFactory.getLogger(AccessMonitor.class);

    private AccessMonitor(){}

    public static class AccessMonitorHolder{
        public static final AccessMonitor INSTANCE = new AccessMonitor();
    }

    // 未持久化的访问量
    public final AtomicInteger transientAccess = new AtomicInteger(0);

    private static ExecutorService executorService
            = new ThreadPoolExecutor(1, 1, 200, TimeUnit.MILLISECONDS,
            new LinkedBlockingDeque<>());

    // 访问量持久化service
    private AccessPVService accessPVService;

    // 访问量持久化阈值, 当transientAccess达到该值后, 持久化一次
    private int transientPushThreshold = 100;

    private Object lock = new Object();

    private void initAccessPVService(){
        if(accessPVService == null){
            synchronized (lock){
                if(accessPVService == null){
                    accessPVService = SpringBean.getBean(AccessPVService.class);
                }
            }
        }
    }

    /**
     * 获取当前网站总访问量
     * @return
     */
    public long getTotalAccess(){
        initAccessPVService();
        return transientAccess.get() + accessPVService.queryAccessNum();
    }

    /**
     * 触发记录访问
     * @param ipAddr
     */
    public void access(String ipAddr){
        logger.info(ipAddr);
        // 非精确统计
        if(transientAccess.addAndGet(1) >= transientPushThreshold){
            synchronized (transientAccess){
                if(transientAccess.get() >= transientPushThreshold){
                    int tempNum = transientAccess.get();
                    transientAccess.set(0);
                    initAccessPVService();
                    executorService.execute(() -> accessPVService.incrementPVAccess(tempNum));
                }
            }
        }

//        if(currentTime - tailBlock.getMilliStart() > singleLiveBlockSize){
//            LiveBlock tempRef = transientBlock;
//            tailBlock.setNext(tempRef);
//            tailBlock = tailBlock.getNext();
//            transientBlock.setMilliStart(currentTime);
//        }else{
//            transientBlock = new LiveBlock(currentTime);
//        }
//        tailBlock.pushIP(ipAddr);
    }

    // 指定该时间范围内的访问均为活跃访问
    private static final int liveRange = 5 * 60 * 1000;

    private static final int singleLiveBlockSize = 30 * 1000;

}
